package cn.catsdad.service.impl;

import cn.catsdad.base.page.PageBean;
import cn.catsdad.base.page.PageParam;
import cn.catsdad.base.service.impl.BaseCrudServiceImpl;
import cn.catsdad.constant.enumConstant.GenericStatus;
import cn.catsdad.dto.MenuDTO;
import cn.catsdad.exception.BaseException;
import cn.catsdad.page.MenuParam;
import cn.catsdad.repository.MenuRepository;
import cn.catsdad.service.api.MenuService;
import cn.catsdad.service.api.RoleMenuService;
import cn.catsdad.service.api.RoleUserService;
import cn.catsdad.util.StringUtil;
import cn.catsdad.util.TreeUtil;
import cn.catsdad.vo.TreeNodeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * 菜单service实现
 *
 * @author xuyonglong
 * @version V1.0 2023/4/13
 */
@Service
public class MenuServiceImpl extends BaseCrudServiceImpl<MenuDTO, Long, MenuRepository>
        implements MenuService {

    private RoleUserService roleUserService;
    private RoleMenuService roleMenuService;

    /**
     * 组装树形
     *
     * @param menuParam 查询参数
     * @return 完成组装的树形
     */
    @Override
    public List<TreeNodeVO> queryTree(MenuParam menuParam) {
        PageBean<MenuDTO> menuPageBean = new PageBean<MenuDTO>()
                .setSize(Integer.MAX_VALUE).setPage(1);
        pageQuery(menuPageBean, menuParam);
        List<MenuDTO> menus = menuPageBean.getQueryResult();
        List<TreeNodeVO> treeNodeVOList = new ArrayList<>(menus.size());
        for (MenuDTO menu : menus) {
            treeNodeVOList.add(menu.initTreeNode());
        }
        return TreeUtil.buildTree(treeNodeVOList, TreeUtil.Sort.ASC);
    }

    @Override
    public void pageQuery(PageBean<MenuDTO> page, PageParam param) {
        page.setEntityName("MenuDTO m");
        page.setQuery("select m");
        super.pageQuery(page, param);
    }

    /**
     * 查询未删除、状态为正常的菜单数据
     *
     * @return 菜单数据
     */
    @Override
    public List<MenuDTO> queryNormalMenus() {
        return repository.findByIsDeletedFalseAndStatusNot(GenericStatus.DEACTIVATE.getValue());
    }

    /**
     * 查询用户具备的权限
     *
     * @param userId 用户id
     * @return 权限编码
     */
    @Override
    public List<MenuDTO> queryMenuOfUser(Long userId) {
        List<MenuDTO> result = new ArrayList<>();
        List<Long> roleIds = roleUserService.queryRoleIdByUserIdIn(Collections.singleton(userId));
        Set<Long> menuIds = roleMenuService.queryMenuIdsByRoles(roleIds);
        if (StringUtil.isNotEmpty(menuIds)) {
            result = repository.findByIdInAndIsDeletedFalseAndStatusNot(menuIds, GenericStatus.DEACTIVATE.getValue());
        }
        return result;
    }

    @Override
    @Transactional
    public MenuDTO save(MenuDTO entity) {
        validation(entity);
        return super.save(entity);
    }

    private void validation(MenuDTO entity) {
        Integer count = repository.countByNameAndTypeAndIdNotAndIsDeletedFalse(entity.getName(), entity.getType(), entity.getId());
        if (count > 0) {
            throw new BaseException("已存在当前功能项！");
        }
    }

    @Autowired
    public void setRoleMenuService(RoleMenuService roleMenuService) {
        this.roleMenuService = roleMenuService;
    }

    @Autowired
    public void setRoleUserService(RoleUserService roleUserService) {
        this.roleUserService = roleUserService;
    }
}
